home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 Applications 1996 May / SGI IRIX 6.2 Applications 1996 May.iso / dist / impr_dev.idb / usr / impressario / src / libprintui / RootWin.c.z / RootWin.c
C/C++ Source or Header  |  1996-05-06  |  13KB  |  411 lines

  1. /**************************************************************************
  2.  *
  3.  *           Copyright (c)    1993 Silicon Graphics, Inc.
  4.  *            All Rights Reserved
  5.  *
  6.  *       THIS    IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
  7.  *
  8.  * The copyright notice above does not evidence any actual of intended
  9.  * publication of such source code, and is an unpublished work by Silicon
  10.  * Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is
  11.  * the property of Silicon Graphics, Inc. Any use, duplication or
  12.  * disclosure not specifically authorized by Silicon Graphics is strictly
  13.  * prohibited.
  14.  *
  15.  * RESTRICTED RIGHTS LEGEND:
  16.  *
  17.  * Use, duplication or disclosure by the Government is subject to
  18.  * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
  19.  * Technical Data and Computer Software clause at DFARS 52.227-7013,
  20.  * and/or in similar or successor clauses in the FAR, DOD or NASA FAR
  21.  * Supplement. Unpublished - rights reserved under the Copyright Laws of
  22.  * the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
  23.  * Shoreline Blvd., Mountain View, CA 94039-7311
  24.  **************************************************************************
  25.  *
  26.  * File: RootWin.c
  27.  *
  28.  * Description: RootWin is a widget that acts as a widget for the root
  29.  *    or any other X window. This allows one to use Xt functions on the
  30.  *    window. One use of this widget is to call XtAddEventHandler on the
  31.  *    root window to get such events as MapNotify to tell us when something
  32.  *    maps on the root window.
  33.  *
  34.  *    CAVEATS:
  35.  *        1. If a window other than the root window is specified, DO NOT
  36.  *           unrealize the widget. Unrealizing the widget in this case
  37.  *           will destroy the window. The root window is immune to this
  38.  *           behavior. It is permissable to destroy the widget.
  39.  *
  40.  *        2. Be aware that only one instance of this widget is created
  41.  *           per window per application. After the initial instance of
  42.  *           this widget is created for a window all subsequent calls
  43.  *           to _PuiCreateRootWin will return the original widget ID.
  44.  *           Therefore, if you add an event handler you may get called
  45.  *           unexpectedly; verify your events.
  46.  *
  47.  *    NOTES:
  48.  *        1. The widget must be managed. Map events will not be
  49.  *           generated because the mapped_when_managed core resource
  50.  *           is explicitly set to False.
  51.  *
  52.  *        2. If a window is not specified (via the PuiNwindow resource),
  53.  *           the root window is assumed. To change the window after
  54.  *           widget creation, you must unrealize the widget, set the
  55.  *           PuiNwindow resource and the realize the widget.
  56.  *
  57.  **************************************************************************/
  58.  
  59.  
  60. #ident "$Revision: 1.3 $"
  61.  
  62.  
  63. #include <stdio.h>
  64. #include <unistd.h>
  65. #include <msgs/uxsgiimpr.h>
  66. #include <X11/IntrinsicP.h>
  67. #include <X11/StringDefs.h>
  68. #include "RootWinP.h"
  69.  
  70.  
  71. /* Resource offset macro */
  72.  
  73. #define offset(field)   XtOffsetOf(PuiRootWinRec, field)
  74.  
  75.  
  76. /* Widget methods */
  77.  
  78. static void Initialize(Widget, Widget, ArgList, Cardinal*);
  79. static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
  80. static void Realize(Widget, XtValueMask*, XSetWindowAttributes*);
  81. static void Destroy(Widget);
  82.  
  83.  
  84. /* Widget resources */
  85.  
  86. static XtResource resources[] = {
  87.     /* Window for which we are a widget */
  88.     {
  89.     PuiNwindow, PuiCWindow, XtRWindow, sizeof(Window),
  90.     offset(rootWin.res_window), XtRImmediate, (XtPointer)NULL
  91.     },
  92. };
  93.  
  94.  
  95. /* Class record initialization */
  96.  
  97. PuiRootWinClassRec puiRootWinClassRec = {
  98.     {        /* Core class fields */
  99.     /* superclass */        (WidgetClass)&coreClassRec,
  100.     /* class_name */        "PuiRootWin",
  101.     /* widget_size */        sizeof(PuiRootWinRec),
  102.     /* class_initialize */        NULL,
  103.     /* class_part_initialize */    NULL,
  104.     /* class_inited */        False,
  105.     /* initialize */        Initialize,
  106.     /* initialize_hook */        NULL,
  107.     /* realize */            Realize,
  108.     /* actions */            NULL,
  109.     /* num_actions */        0,
  110.     /* resources */            resources,
  111.     /* num_resources */        XtNumber(resources),
  112.     /* xrm_class */            NULLQUARK,
  113.     /* compress_motion */        True,
  114.     /* compress_exposure */        True,
  115.     /* compress_enterleave */    True,
  116.     /* visible_interest */        False,
  117.     /* destroy */            Destroy,
  118.     /* resize */            XtInheritResize,
  119.     /* expose */            XtInheritExpose,
  120.     /* set_values */        SetValues,
  121.     /* set_values_hook */        NULL,
  122.     /* set_values_almost */        XtInheritSetValuesAlmost,
  123.     /* get_values_hook */        NULL,
  124.     /* accept_focus */        XtInheritAcceptFocus,
  125.     /* version */            XtVersion,
  126.     /* callback_private */        NULL,
  127.     /* tm_table */            NULL,
  128.     /* query_geometry */        XtInheritQueryGeometry,
  129.     /* display_accelerator */    XtInheritDisplayAccelerator,
  130.     /* extension */            NULL,
  131.     },
  132.     {        /* PuiRootWin class fields */
  133.     /* dummy */            NULL,
  134.     }
  135. };
  136.  
  137. WidgetClass puiRootWinWidgetClass = (WidgetClass)&puiRootWinClassRec;
  138.  
  139.  
  140. /* Undocumented Xt external functions */
  141. /*    XtRegisterWindow hashes a window with a widget so that event arriving
  142.     on a window can be sent to the appropriate widget. XtUnregisterWindow
  143.     destroys the hashing.
  144. */
  145.  
  146. extern void _XtRegisterWindow(Window, Widget);
  147. extern void _XtUnregisterWindow(Window, Widget);
  148.  
  149.  
  150. /* Local functions */
  151.  
  152. static void SetCoreMembers(Widget w);
  153.  
  154.  
  155. /*
  156.  =======================================================================
  157.             STANDARD WIDGET METHODS
  158.  =======================================================================
  159.  */
  160.  
  161.  
  162. /**************************************************************************
  163.  *
  164.  * Function: Initialize
  165.  *
  166.  * Description: Widget initialization method.
  167.  *
  168.  * Parameters: 
  169.  *    treq (I) - widget as set by arg list, resource database and defaults
  170.  *    tnew (I) - new widget
  171.  *    args (I) - argument list in Va creation
  172.  *    num_args (I) - number of arguments
  173.  *
  174.  * Return: none
  175.  *
  176.  **************************************************************************/
  177.  
  178. static void Initialize(Widget treq, Widget tnew, ArgList args,
  179.                         Cardinal *num_args)
  180. {
  181.     register PuiRootWinPart *rwp = &((PuiRootWinWidget)tnew)->rootWin;
  182.  
  183.     /*
  184.      * Set certain key core member fields
  185.      */
  186.     SetCoreMembers(tnew);
  187.  
  188.     /*
  189.      * We need to set the window in the initialize routine because we need
  190.      * XtWindowToWidget to work as soon as the widget is created. That way
  191.      * we prevent multiple of these widgets being created for the same
  192.      * window. Setting the window here does not hurt anything. It only
  193.      * means that Xt will think we are realized and not call our realize
  194.      * routine. That is OK too since the only thing the realize routine does
  195.      * that we don't do here is setting event masks with select input. Since
  196.      * Xt thinks we're realized, it will call select input anyway if we add
  197.      * an event handler.
  198.      *
  199.      * Determine whether a window has been specified or if we should
  200.      * default to the root window. We simply set our core window field
  201.      * to the existing window's ID and we now have a widget for the
  202.      * window.
  203.      */
  204.     if (rwp->res_window)
  205.         XtWindow(tnew) = rwp->res_window;
  206.     else
  207.         XtWindow(tnew) = RootWindowOfScreen(XtScreen(tnew));
  208.     _XtRegisterWindow(XtWindow(tnew), tnew);
  209. }
  210.  
  211.  
  212. /**************************************************************************
  213.  *
  214.  * Function: Realize
  215.  *
  216.  * Description: The widget realize method.
  217.  *
  218.  * Parameters: Standard Realize procedure parameters
  219.  *
  220.  * Return: none
  221.  *
  222.  **************************************************************************/
  223.  
  224. static void Realize(Widget w, XtValueMask *valueMask,
  225.                     XSetWindowAttributes *attributes)
  226. {
  227.     register PuiRootWinPart *rwp = &((PuiRootWinWidget)w)->rootWin;
  228.     XWindowAttributes xwa;
  229.  
  230.     /*
  231.      * Determine whether a window has been specified or if we should
  232.      * default to the root window. We simply set our core window field
  233.      * to the existing window's ID and we now have a widget for the
  234.      * window.
  235.      */
  236.     if (rwp->res_window)
  237.         XtWindow(w) = rwp->res_window;
  238.     else
  239.         XtWindow(w) = RootWindowOfScreen(XtScreen(w));
  240.  
  241.     /*
  242.      * Get the window's attributes for our event mask and for setting
  243.      * our core memeber fields.
  244.      */
  245.     XGetWindowAttributes(XtDisplay(w), XtWindow(w), &xwa);
  246.  
  247.     /*
  248.      * We need to explicitly set the event mask on the window
  249.      * to make sure that we get the events. This is because no
  250.      * new window has been created. Normally the event mask is
  251.      * set on window creation in the event mask field of the window
  252.      * attributes.
  253.      */
  254.     XSelectInput(XtDisplay(w), XtWindow(w), xwa.your_event_mask | 
  255.                         attributes->event_mask);
  256. }
  257.  
  258.  
  259. /**************************************************************************
  260.  *
  261.  * Function: Destroy
  262.  *
  263.  * Description: Called on widget destruction. We set the widget window
  264.  *    ID to None so that the window does not get destroyed.
  265.  *
  266.  * Parameters: 
  267.  *    w (I) - this widget
  268.  *
  269.  * Return: none
  270.  *
  271.  **************************************************************************/
  272.  
  273. static void Destroy(Widget w)
  274. {
  275.     _XtUnregisterWindow(XtWindow(w), w);
  276.     XtWindow(w) = None;
  277. }
  278.  
  279.  
  280. /**************************************************************************
  281.  *
  282.  * Function: SetValues
  283.  *
  284.  * Description: Handles the setting of resource values by the XtSetValues
  285.  *    Xt function.
  286.  *
  287.  * Parameters:
  288.  *    cur (I) - current settings of widget variables
  289.  *    req (I) - requested values of widget variables not processed
  290.  *            by superclass.
  291.  *    new (I) - new widget values already processed by superclass
  292.  *    args (I) - arguments to SetValues function
  293.  *    num_args (I) - number of arguments in args
  294.  *
  295.  * Return: True if XClearArea is to be called and expose event generated,
  296.  *    Flase if no redisplay required.
  297.  *
  298.  **************************************************************************/
  299. /* ARGSUSED */
  300.  
  301. static Boolean SetValues(Widget cur, Widget req, Widget new,
  302.                     ArgList args, Cardinal *num_args)
  303. {
  304.     register PuiRootWinPart *crwp = &((PuiRootWinWidget)cur)->rootWin;
  305.     register PuiRootWinPart *nrwp = &((PuiRootWinWidget)new)->rootWin;
  306.  
  307.     /* Window to monitor */
  308.     if ((crwp->res_window != nrwp->res_window) && XtIsRealized(new)) {
  309.     nrwp->res_window = crwp->res_window;
  310.     XtWarning(gettxt(_SGI_LIBPRINTUI_WINCHANGE,
  311.         "PuiRootWin - cannot change PuiNwindow after widget realization"));
  312.     }
  313.  
  314.     return False;
  315. }
  316.  
  317.  
  318. /*
  319.  ==========================================================================
  320.                 LOCAL FUNCTIONS
  321.  ==========================================================================
  322. */
  323.  
  324.  
  325. /**************************************************************************
  326.  *
  327.  * Function: SetCoreMembers
  328.  *
  329.  * Description: Sets a basic set of core member fields so that GetValues
  330.  *    on these fields return something defined. We set dimension fields
  331.  *    to 0 so that there is no visible layout effect on the parent.
  332.  *
  333.  * Parameters: 
  334.  *    w (I) - this widget
  335.  *
  336.  * Return: none
  337.  *
  338.  **************************************************************************/
  339.  
  340. static void SetCoreMembers(register Widget w)
  341. {
  342.     w->core.x = 0;
  343.     w->core.y = 0;
  344.     w->core.width = 0;
  345.     w->core.height = 0;
  346.     w->core.border_width = 0;
  347.     w->core.mapped_when_managed = False;
  348. }
  349.  
  350.  
  351. /*
  352.  ==========================================================================
  353.                         PUBLIC AND CONVENIENCE FUNCTIONS
  354.  ==========================================================================
  355. */
  356.  
  357.  
  358. /**************************************************************************
  359.  *
  360.  * Function: _PuiCreateRootWin
  361.  *
  362.  * Description: Creates a managed RootWin widget if one does not already
  363.  *    exist for the specified window. Note that this function ensures
  364.  *    that there is only on RootWin widget per window.
  365.  *
  366.  * Parameters:
  367.  *      parent (I) - parent widget ID
  368.  *      name (I) - instance name for newly created widget
  369.  *      args (I) - widget resource settings
  370.  *      num (I) - number of resources specified.
  371.  *
  372.  * Return: Widget ID of newly created RootWin widget.
  373.  *
  374.  **************************************************************************/
  375.  
  376. Widget _PuiCreateRootWin(Widget parent, String name, ArgList args,
  377.                             Cardinal num)
  378. {
  379.     Widget widget;
  380.     Window win = None;
  381.     ArgList aptr;
  382.     int i;
  383.  
  384.     /*
  385.      * See if a window ID has been specified as a resource
  386.      */
  387.     for (i = 0, aptr = args; i < num; i++, aptr++) {
  388.     if (strcmp(aptr->name, PuiNwindow) == 0 ||
  389.             strcmp(aptr->name, PuiCWindow) == 0)
  390.         win = aptr->value;
  391.     }
  392.  
  393.     /*
  394.      * If no window specified, use the root window
  395.      */
  396.     if (win == None)
  397.     win = RootWindowOfScreen(XtScreen(parent));
  398.  
  399.     /*
  400.      * If a widget already exists for this window we must use that
  401.      * since Xt only understands one widget per window. If there is
  402.      * no widget for the window, create a RootWin widget for the window.
  403.      */
  404.     if ((widget = XtWindowToWidget(XtDisplay(parent), win)) == NULL)
  405.         widget = XtCreateManagedWidget(name, puiRootWinWidgetClass,
  406.                             parent, args, num);
  407.  
  408.     return widget;
  409. }
  410.  
  411.